
package com.bsoft.gol.hcb.service.pay.diagnosis;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsoft.gol.hcb.dao.prescriptionCirculation.OdsOrderExpenseRecordDAO;
import com.bsoft.gol.hcb.dao.prescriptionCirculation.OdsOrderPrescriptionInfoDAO;
import com.bsoft.gol.hcb.utils.*;
import com.bsoft.gol.mpi.model.Card;
import com.bsoft.gol.mpi.model.Certificate;
import com.bsoft.gol.mpi.model.Person;
import com.bsoft.gol.mpi.model.Unique;
import com.bsoft.gol.mpi.provider.IMPIProvider;
import com.bsoft.gol.mpi.service.MPIException;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import ctd.account.UserRoleToken;
import ctd.controller.exception.ControllerException;
import ctd.net.rpc.Client;
import ctd.spring.boot.annotation.SsdevReference;
import ctd.spring.boot.annotation.SsdevService;
import ctd.util.JSONUtils;
import ctd.util.annotation.RpcService;
import hcn.base.BasePropertyConfig;
import hcn.base.Device;
import hcn.base.Organization;
import hcn.base.clinicguide.ClinicGuideTipDTO;
import hcn.base.clinicguide.ClinicGuideTipVO;
import hcn.bean.voucher.GetUsableVoucherListQo;
import hcn.common.CodeDefinition;
import hcn.common.Constants;
import hcn.common.ContextHelper;
import hcn.ods.DiagnosisPayTradeDetail;
import hcn.ods.PayTrade;
import hcn.pay.PayType;
import hcn.protocol.ods.FeeDetailRequestBean;
import hcn.protocol.ods.PrecalculatedFeeRequestBean;
import hcn.protocol.ods.UnpayedRecordsRequestBean;
import hcn.protocol.ods.newdiagnosis.*;
import hcn.protocol.ods.paymentXML.GetUsableVoucherListReq;
import hcn.protocol.ods.paymentXML.GetUsableVoucherListResp;
import hcn.util.BaseResponse;
import hcn.util.IdentityTransformUtil;
import hcn.util.validation.AnnotaionException;
import hcn.util.validation.ValidationUtil;
import mpi.security.cipher.sm.SM4Utils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import pcn.bean.consultation.GetDrugOrderPrecalculatedFeeQo;
import pcn.enums.FeeTypeEnum;
import pcn.vo.base.QueryDicContrastListVo;
import service.rpc.*;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

//import pcn.service.web.MpiIdentityService;

/**
 * @author <a href="mailto:chinnsii@163.com">zhengshi</a>
 */
@SsdevService("diagnosisPayTrade")
public class DiagnosisPayTradeService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DiagnosisPayTradeService.class);
    private static Logger logger = LoggerFactory.getLogger(DiagnosisPayTradeService.class);

    private String adapterServiceName = "diagnosisPayment";
    private String getUnpayedRecordsMethodName = "getUnpayedRecords";
    private String getPayedRecordsMethodName = "getPayedRecords";
    private String getPrecalculatedFeeMethodName = "getPrecalculatedFee";
    private String getFeeRecordDetailMethodName = "getFeeDetail";
    @SsdevReference("gol-mpi.mpiProvider")
    private IMPIProvider mpiProvider;
    @Autowired
    @Qualifier("hcnPayTradeService")
    private PayTradeIntf payTradeService;

    @Autowired
    @Qualifier("hcnPayTradeService")
    private PayTradeIntf payTradeIntf;
    @Autowired
    private BasePropertyConfigIntf basePropertyConfigIntf;

    @Autowired
    private OrganizationInfoIntf organizationInfoService;
    @Autowired
    private PersonServiceIntf personServiceIntf;
    @Autowired
    private OdsOrderPrescriptionInfoDAO odsOrderPrescriptionInfoDAO;
    @Autowired
    private OdsOrderExpenseRecordDAO odsOrderExpenseRecordDAO;
    @Autowired
    private DicContrastService dicContrastService;


    protected TradeType getTradeType() {
        return TradeType.diagnosisFee;
    }


    @SuppressWarnings("unchecked")
    protected <T> T invokeAdapter(String serviceName, String methodName, int errorCodeIfOccured, String errorMsgIfOccurred, Object... params) throws ControllerException {
        try {
            return (T) Client.rpcInvoke(serviceName, methodName, params);
        } catch (Throwable e) {
            throw new ControllerException(e, errorCodeIfOccured, errorMsgIfOccurred == null ? e.getMessage() :
                    errorMsgIfOccurred);
        }
    }

    /**
     * 获取待支付提示
     */
    @RpcService
    public ClinicGuideTipVO queryUnPayedRecordsTip(ClinicGuideTipDTO dto) {
        UnpayedRecordsRequestBean request = new UnpayedRecordsRequestBean();
        request.setMpiId(dto.getMpiId());
        request.setOrgId(dto.getOrgId());
        request.setExecutionType(2);
        request.setOutpatientType(1);
        ClinicGuideTipVO vo = new ClinicGuideTipVO();
        Integer tip = 0;
        try {
            List<NewQueryUnPayListResponseBean> list = queryUnPayedRecordsList(request);
            if (CommonUtils.isNotEmpty(list)) {
                tip = list.size();
            }
        } catch (Exception e) {
            logger.error("获取用户待支付列表失败", e);
        }
        vo.setTip(tip);
        return vo;
    }

    /**
     * @description: 获取待支付列表，诊间支付与云支付的共同接口，于2020年6月18日19:39:06生效
     * @author: chenJij@bsoft.com.cn
     * @date: 2020/6/18 19:35
     * @param: request
     * @return: java.util.List<hcn.protocol.ods.newdiagnosis.NewQueryUnPayListResponseBean>
     */
    @RpcService
    public List<NewQueryUnPayListResponseBean> queryUnPayedRecordsList(UnpayedRecordsRequestBean request) throws Exception {

        logger.info(" 获取支付 入参queryUnPayedRecordsList：" + JSONUtils.writeValueAsString(request));

        try {
            ValidationUtil.validation(request);//入参格式校验
        } catch (AnnotaionException e) {
            e.printStackTrace();
            throw new ControllerException(CodeDefinition.CANNOT_GET_UNPAYED_RECORDS, e.getMessage());
        }
        Organization organization = organizationInfoService.getOrgDetailByOrgId(request.getOrgId());
        if (organization == null) {
            throw new ControllerException(CodeDefinition.CANNOT_GET_UNPAYED_RECORDS, "机构不存在");
        }
        if (organization.getLocalOrgId() == null) {
            throw new ControllerException(CodeDefinition.CANNOT_GET_UNPAYED_RECORDS, "机构localOrgId未配置");
        }

        //云支付数据获取
        if (2 == request.getOutpatientType().intValue()) {
            //从本地获取云支付已支付列表数据
            try {
                List<NewQueryUnPayListResponseBean> responseBeans = (List<NewQueryUnPayListResponseBean>) Client.rpcInvoke("hcb.cloudPayService", "queryLocalUnPayedRecordList", request);

                return responseBeans;
            } catch (Throwable throwable) {
                throwable.printStackTrace();
                throw new ControllerException(CodeDefinition.CANNOT_GET_PAYED_RECORDS, "获取已支付列表失败");
            }
        /*}else if (3 == request.getOutpatientType().intValue()){
            //从本地获取自主开单待支付列表数据
            try {
                List<NewQueryUnPayListResponseBean> responseBeans = (List<NewQueryUnPayListResponseBean> )Client.rpcInvoke("hcb.cloudPayService", "queryNatUnPayedRecordList", request);

                return responseBeans;
            } catch (Throwable throwable) {
                throwable.printStackTrace();
                throw new ControllerException(CodeDefinition.CANNOT_GET_PAYED_RECORDS, "获取已支付列表失败");
            } 自主开单取诊间支付数据*/
        } else {
            //诊间支付数据获取
            LOGGER.info("HCN-WEB获取待支付列表入参--->{}", request);
            Object[] args2;
            Object[] args;

            //门诊类型从机构表里获取
            String outpatientType = organization.getOutpatientType();
            request.setOutpatientType(CommonUtils.isEmpty(outpatientType) ? 101 : Integer.valueOf(organization.getOutpatientType()));

            String localOrgId = organization.getLocalOrgId();
            //不选卡
            args = resolveFeeRecordsArguments(request.getMpiId(), localOrgId, request.getExecutionType());
            args2 = new Object[args.length + 2];
            System.arraycopy(args, 0, args2, 0, args.length);
            args2[args.length] = request.getOutpatientType();
            //获取his Url
            args2[args.length + 1] = organization.getProHisUrl();
            BaseResponse<List<NewQueryUnPayListResponseBean>> baseResponse = new BaseResponse<>();
            BasePropertyConfig propertyCode = basePropertyConfigIntf.getPropertyConfigByPropertyCode("013708", organization.getOrgId());
            if (null != propertyCode && "1".equals(propertyCode.getPropertyData())) {
                baseResponse = invokeAdapter("hcnInterface.diagnosisPayTradeService", "getUnPayedRecordsXML",
                        CodeDefinition.CANNOT_GET_UNPAYED_RECORDS, "获取待支付列表失败。", args2);
            } else {
                baseResponse = invokeAdapter("hcnInterface.diagnosisPayTradeService", "queryUnPayedRecords",
                        CodeDefinition.CANNOT_GET_UNPAYED_RECORDS, "获取待支付列表失败。", args2);
            }

            //过滤待支付记录
            if (null != baseResponse) {
                operateOffLineUnPayedRecords(baseResponse.getData(), request.getOrgId(), organization.getLocalOrgId());
            }

            //HIS的字典对照赋值
            Map<String, String> hisDicMap = new HashMap<>();
            List<QueryDicContrastListVo> queryDicContrastListVos = dicContrastService.queryDicContrastList("fee_type", organization.getOrgId());
            if (CommonUtils.isNotEmpty(queryDicContrastListVos)) {
                for (QueryDicContrastListVo queryDicContrastListVo : queryDicContrastListVos) {
                    hisDicMap.put(queryDicContrastListVo.getHisItemCode(), queryDicContrastListVo.getBaseItemCode());
                }
            }

            LOGGER.info("hcnInterface返回：{}", JSON.toJSONString(baseResponse));
            if (baseResponse.getCode() == ResponseCode.SUCCESS) {
                List<NewQueryUnPayListResponseBean> list = JSONArray.parseArray(JSONArray.toJSONString(baseResponse.getData()), NewQueryUnPayListResponseBean.class);
                if (CommonUtils.isNotEmpty(list)) {
                    for (NewQueryUnPayListResponseBean newQueryUnPayListResponseBean : list) {
                        if (CommonUtils.isNotEmpty(newQueryUnPayListResponseBean.getMergingItems())) {
                            //把HIS的字典转成标准的费用字典
                            for (NewQueryUnPayListResponseBean.MergingItemsBean mergingItemsBean : newQueryUnPayListResponseBean.getMergingItems()) {
                                //机构代码赋值，查询检查申请单详情时会用到
                                mergingItemsBean.setOrganizationId(localOrgId);
                                if (hisDicMap.keySet().contains(mergingItemsBean.getFeeTypeCode())) {
                                    mergingItemsBean.setFeeTypeCode(hisDicMap.get(mergingItemsBean.getFeeTypeCode()));
                                }
                            }
                        }
                    }
                    return sortResponse(list);
                }
                return null;
            } else {
                throw new ControllerException(CodeDefinition.CANNOT_GET_UNPAYED_RECORDS, "获取待支付列表失败" + baseResponse.getMessage());
            }
        }
    }


    /**
     * @description: 处理诊间支付的待支付记录, 院外流转的处方就不出现在待支付列表里面
     * @author: chenJij@bsoft.com.cn
     * @date: 2021/8/30 13:38
     * @param: baseResponse
     * @param: orgId
     * @return: BaseResponse<java.util.List < hcn.protocol.ods.newdiagnosis.NewQueryUnPayListResponseBean>>
     */
    public void operateOffLineUnPayedRecords(List<NewQueryUnPayListResponseBean> data, String orgId, String organizationId) {

        List<NewQueryUnPayListResponseBean.MergingItemsBean> itemsBeans;
        if (CommonUtils.isNotEmpty(data)) {
            for (NewQueryUnPayListResponseBean newGetUnpayListResponseBean : data) {
                if (CommonUtils.isNotEmpty(newGetUnpayListResponseBean.getMergingItems())) {

                    itemsBeans = new ArrayList<>();
                    for (NewQueryUnPayListResponseBean.MergingItemsBean mergingItem : newGetUnpayListResponseBean.getMergingItems()) {
                        //处方待支付记录，需要判断本地是否存在待支付或者已支付的处方订单，若是存在，就过滤
                        if (FeeTypeEnum.XIYAO.getTitle().equals(mergingItem.getFeeTypeCode())
                                || FeeTypeEnum.CHENGYAO.getTitle().equals(mergingItem.getFeeTypeCode())
                                || FeeTypeEnum.CAOYAO.getTitle().equals(mergingItem.getFeeTypeCode())) {
                            long payedCount = odsOrderPrescriptionInfoDAO.getPayedCount(orgId, mergingItem.getFeeNo());
                            //不存在就添加到待支付列表里
                            if (payedCount == 0) {
                                itemsBeans.add(mergingItem);
                            } else {
                                newGetUnpayListResponseBean.setUnPayRecordFlag("1");
                            }
                        } else {
                            long payedCount = odsOrderExpenseRecordDAO.getPayedCount(organizationId, mergingItem.getFeeNo());
                            if (0 == payedCount) {
                                payedCount = odsOrderExpenseRecordDAO.getPayedCountByExpenseId(organizationId, mergingItem.getFeeNo());
                            }
                            //不存在就添加到待支付列表里
                            if (payedCount == 0) {
                                itemsBeans.add(mergingItem);
                            } else {
                                newGetUnpayListResponseBean.setUnPayRecordFlag("1");
                            }
                        }
                    }
                    newGetUnpayListResponseBean.setMergingItems(itemsBeans);
                }
            }
        }
    }

    /**
     * @description: 分类处理诊间支付数据返回
     * @author: chenJij@bsoft.com.cn
     * @date: 2021/9/24 13:04
     * @param: newQueryUnPayListResponseBean
     * @return: java.util.List<hcn.protocol.ods.newdiagnosis.NewQueryUnPayListResponseBean>
     */
    public List<NewQueryUnPayListResponseBean> sortResponse(List<NewQueryUnPayListResponseBean> newQueryUnPayListResponseBeanList) {

        //就诊序号—费用类型，费用集合的map
        Map<String, List<NewQueryUnPayListResponseBean.MergingItemsBean>> serialNumberAndFeeTypeCodeMap = new HashMap<>();

        if (CommonUtils.isNotEmpty(newQueryUnPayListResponseBeanList)) {
            for (NewQueryUnPayListResponseBean newQueryUnPayListResponseBean : newQueryUnPayListResponseBeanList) {
                for (NewQueryUnPayListResponseBean.MergingItemsBean itemsBean : newQueryUnPayListResponseBean.getMergingItems()) {
                    String feeTypeCode = itemsBean.getFeeTypeCode();
                    String key = itemsBean.getSerialNumber() + "^" + itemsBean.getFeeTypeCode();
                    //药品的放一起
                    if (FeeTypeEnum.XIYAO.getTitle().equals(feeTypeCode)
                            || FeeTypeEnum.CHENGYAO.getTitle().equals(feeTypeCode)
                            || FeeTypeEnum.CAOYAO.getTitle().equals(feeTypeCode)) {
                        key = itemsBean.getSerialNumber() + "^1_2_3";
                    }

                    List<NewQueryUnPayListResponseBean.MergingItemsBean> mergingItemsBeanList = serialNumberAndFeeTypeCodeMap.get(key);
                    if (null == mergingItemsBeanList) {
                        mergingItemsBeanList = new ArrayList<>();
                    }
                    mergingItemsBeanList.add(itemsBean);
                    serialNumberAndFeeTypeCodeMap.put(key, mergingItemsBeanList);
                }
            }
        }


        //遍历每个类型
        if (CommonUtils.isNotEmpty(serialNumberAndFeeTypeCodeMap.keySet())) {

            List<NewQueryUnPayListResponseBean> newQueryUnPayListResponseBeans = new ArrayList<>();
            NewQueryUnPayListResponseBean unPayListResponseBean = null;

            for (List<NewQueryUnPayListResponseBean.MergingItemsBean> mergingItemsBeanList : serialNumberAndFeeTypeCodeMap.values()) {

                String feeTypeCode = mergingItemsBeanList.get(0).getFeeTypeCode();
                String recordType = "";
                String recordTypeName = "";
                if (FeeTypeEnum.XIYAO.getTitle().equals(feeTypeCode)
                        || FeeTypeEnum.CHENGYAO.getTitle().equals(feeTypeCode)
                        || FeeTypeEnum.CAOYAO.getTitle().equals(feeTypeCode)) {
                    recordType = "1";
                    recordTypeName = "处方";
                } else {
                    recordType = feeTypeCode;
                    try {
                        recordTypeName = FeeTypeEnum.getDescription(feeTypeCode).getContext();
                    } catch (Exception e) {
                        recordType = "99";
                        recordTypeName = "其他";
                    }
                }

                unPayListResponseBean = new NewQueryUnPayListResponseBean();
                unPayListResponseBean.setPatientCode(newQueryUnPayListResponseBeanList.get(0).getPatientCode());
                unPayListResponseBean.setPatientMedicalCardType(newQueryUnPayListResponseBeanList.get(0).getPatientMedicalCardType());
                unPayListResponseBean.setPatientMedicalCardNumber(newQueryUnPayListResponseBeanList.get(0).getPatientMedicalCardNumber());
                unPayListResponseBean.setRecordType(recordType);
                unPayListResponseBean.setRecordTypeName(recordTypeName);
                unPayListResponseBean.setUnPayRecordFlag(newQueryUnPayListResponseBeanList.get(0).getUnPayRecordFlag());
                unPayListResponseBean.setConsultId("");
                unPayListResponseBean.setDeptName(mergingItemsBeanList.get(0).getDepartmentName());
                if (mergingItemsBeanList.get(0).getMedicalDate() != null) {
                    unPayListResponseBean.setConsultTime(DateUtils.toDate(mergingItemsBeanList.get(0).getMedicalDate(), "yyyy-MM-dd HH:mm:ss"));
                }
                unPayListResponseBean.setMergingItems(mergingItemsBeanList);

                BigDecimal totalFee = BigDecimal.ZERO;
                for (NewQueryUnPayListResponseBean.MergingItemsBean mergingItemsBean : mergingItemsBeanList) {
                    totalFee = totalFee.add(new BigDecimal(mergingItemsBean.getMergingSubtotal()));
                }
                unPayListResponseBean.setTotalFee(totalFee.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());

                newQueryUnPayListResponseBeans.add(unPayListResponseBean);
            }
            //按日期排序
            try {
                Collections.sort(newQueryUnPayListResponseBeans, new Comparator<NewQueryUnPayListResponseBean>() {
                    @Override
                    public int compare(NewQueryUnPayListResponseBean o1, NewQueryUnPayListResponseBean o2) {
                        Long date1 = o1.getConsultTime().getTime();
                        Long date2 = o2.getConsultTime().getTime();
                        return date2.compareTo(date1);
                    }
                });
            } catch (Exception e) {
                logger.error("排序异常", e);
            }
            return newQueryUnPayListResponseBeans;
            //若是收费项目都没有，那么就返回有待收费项目的集合
        } else if (CommonUtils.isNotEmpty(newQueryUnPayListResponseBeanList)) {
            return newQueryUnPayListResponseBeanList;
        }
        return null;
    }


    /**
     * 获取已支付列表。
     *
     * @return
     * @throws ControllerException
     */
    @RpcService
    public List<NewGetPayedListResponseBean> getPayedRecords(UnpayedRecordsRequestBean request) throws Exception {
        try {
            ValidationUtil.validation(request);//入参格式校验
        } catch (AnnotaionException e) {
            e.printStackTrace();
            throw new ControllerException(CodeDefinition.CANNOT_GET_PAYED_RECORDS, e.getMessage());
        }

        //云支付的已支付记录或者待支付或已取消的订单都是从本地获取
        if (2 == request.getOutpatientType().intValue()) {
            //从本地获取云支付已支付列表数据
            try {
                List<NewGetPayedListResponseBean> responseBeans = (List<NewGetPayedListResponseBean>) Client.rpcInvoke("hcb.cloudPayService", "queryLocalPayedRecords", request);
                return responseBeans;
            } catch (Throwable throwable) {
                throwable.printStackTrace();
                throw new ControllerException(CodeDefinition.CANNOT_GET_PAYED_RECORDS, "获取已支付列表失败");
            }

            //实时从his获取已支付列表
        } else {
            LOGGER.info("HCN-WEB获取已支付列表入参--->{}", request);
            Organization organization = organizationInfoService.getOrgDetailByOrgId(request.getOrgId());
            //门诊类型从机构表里获取
            String outpatientType = organization.getOutpatientType();
            request.setOutpatientType(CommonUtils.isEmpty(outpatientType) ? 101 : Integer.valueOf(organization.getOutpatientType()));

            String localOrgId = organization.getLocalOrgId();

            Object[] args;
            args = resolveFeeRecordsArguments(request.getMpiId(), localOrgId, request.getExecutionType());
            Object[] args2 = new Object[args.length + 1];
            System.arraycopy(args, 0, args2, 0, args.length);
            //获取his Url
            args2[args.length] = organization.getProHisUrl();
            BaseResponse<List<NewGetPayedListResponseBean>> response = new BaseResponse<>();
            BasePropertyConfig propertyCode = basePropertyConfigIntf.getPropertyConfigByPropertyCode("013708", organization.getOrgId());
            if (null != propertyCode && "1".equals(propertyCode.getPropertyData())) {
                response = invokeAdapter("hcnInterface.diagnosisPayTradeService", "getPayedRecordsXML",
                        CodeDefinition.CANNOT_GET_PAYED_RECORDS, "获取已支付列表失败。", args2);
            } else {
                response = invokeAdapter("hcnInterface.diagnosisPayTradeService", "getPayedRecords",
                        CodeDefinition.CANNOT_GET_PAYED_RECORDS, "获取已支付列表失败。", args2);
            }
            LOGGER.info("hcnInterface返回：{}", response);
            if (response.getCode() == ResponseCode.SUCCESS) {
                List<NewGetPayedListResponseBean> newGetPayedListResponseBeans = JSONArray.parseArray(JSONArray.toJSONString(response.getData()), NewGetPayedListResponseBean.class);
                if (CommonUtils.isNotEmpty(newGetPayedListResponseBeans)) {
                    for (NewGetPayedListResponseBean newGetPayedListResponseBean : newGetPayedListResponseBeans) {
                        List<NewGetPayedListResponseBean.InvoiceListBean> invoiceList = newGetPayedListResponseBean.getInvoiceList();

                        if (CommonUtils.isNotEmpty(invoiceList)) {
                            Map<String, NewGetPayedListResponseBean.InvoiceListBean> invoiceListBeanMap = new HashMap<>();
                            for (NewGetPayedListResponseBean.InvoiceListBean invoiceListBean : invoiceList) {
                                invoiceListBeanMap.put(invoiceListBean.getInvoiceNumber(), invoiceListBean);
                            }
                            //查询物流配送的订单数据，相同的发票号的发票订单 替代诊间支付已支付列表里面的信息
                            List<String> invoiceNumberList = invoiceList.stream().map(NewGetPayedListResponseBean.InvoiceListBean::getInvoiceNumber).distinct().collect(Collectors.toList());
                            if (CommonUtils.isNotEmpty(invoiceNumberList)) {
                                request.setInvoiceNumberList(invoiceNumberList);
                                List<NewGetPayedListResponseBean> beanList;
                                try {
                                    beanList = (List<NewGetPayedListResponseBean>) Client.rpcInvoke("hcb.cloudPayService", "queryLocalPayedRecords", request);
                                } catch (Throwable throwable) {
                                    throwable.printStackTrace();
                                    throw new ControllerException(CodeDefinition.CANNOT_GET_PAYED_RECORDS, "获取已支付列表失败");
                                }

                                if (CommonUtils.isNotEmpty(beanList)) {
                                    for (NewGetPayedListResponseBean getPayedListResponseBean : beanList) {
                                        if (CommonUtils.isNotEmpty(getPayedListResponseBean.getInvoiceList())) {
                                            List<NewGetPayedListResponseBean.InvoiceListBean> collect = getPayedListResponseBean.getInvoiceList().stream().filter(invoiceListBean -> invoiceListBeanMap.keySet()
                                                    .contains(invoiceListBean.getInvoiceNumber())).collect(Collectors.toList());

                                            if (CommonUtils.isNotEmpty(collect)) {
                                                for (NewGetPayedListResponseBean.InvoiceListBean invoiceListBean : collect) {
                                                    invoiceListBeanMap.put(invoiceListBean.getInvoiceNumber(), invoiceListBean);
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            List<NewGetPayedListResponseBean.InvoiceListBean> collect = invoiceListBeanMap.values().stream().collect(Collectors.toList());
                            newGetPayedListResponseBean.setInvoiceList(collect);

                            // 进行降序排列
                            Collections.sort(newGetPayedListResponseBean.getInvoiceList(), new Comparator<NewGetPayedListResponseBean.InvoiceListBean>() {
                                public int compare(NewGetPayedListResponseBean.InvoiceListBean o1, NewGetPayedListResponseBean.InvoiceListBean o2) {
                                    Long o1Times = CommonUtils.isEmpty(o1.getFeeDate()) ? 0L : DateUtils.toDate(o1.getCostDate(), "yyyy-MM-dd HH:mm:ss").getTime();
                                    Long o2Times = CommonUtils.isEmpty(o2.getFeeDate()) ? 0L : DateUtils.toDate(o2.getCostDate(), "yyyy-MM-dd HH:mm:ss").getTime();
                                    return o2Times.compareTo(o1Times);
                                }
                            });
                        }
                        //今日支付处理逻辑
                        if (CommonUtils.isNotEmpty(request.getExecutionType()) && request.getExecutionType() == 1) {
                            List<NewGetPayedListResponseBean.InvoiceListBean> collect = newGetPayedListResponseBean.getInvoiceList().stream().filter(item -> {
                                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                                String format = simpleDateFormat.format(DateUtils.toDate(item.getCostDate()));
                                String nowFormat = simpleDateFormat.format(new Date());
                                return format.equals(nowFormat);
                            }).collect(Collectors.toList());
                            newGetPayedListResponseBean.setInvoiceList(collect);
                        }
                    }
                }
                return newGetPayedListResponseBeans;
            }
            throw new ControllerException(CodeDefinition.CANNOT_GET_PAYED_RECORDS, "获取已支付列表" + response.getMessage());
        }
    }

    /**
     * Description: 获取机构卡信息
     *
     * @param orgId
     * @return
     * @throws ControllerException
     */
    private Object[] resolveFeeRecordsArguments(String mpiId, String orgId, int executionType) throws ControllerException {
        List<Map<String, Object>> cardList = null;
        String patientCode = "";
        //构建卡信息
        Set<Card> cards;
        try {
            cards = mpiProvider.getCards(mpiId);
        } catch (MPIException e) {
            throw new ControllerException(CodeDefinition.DEMOGRAPHIC_FAIL, "获取证件,卡信息失败。");
        }
        if (cards != null && !cards.isEmpty()) {
            cardList = new ArrayList<>();
            for (Card card : cards) {
                if (orgId.equals(card.getSource())) {
                    patientCode = card.getPatientCode();
                }
                break;
//                DictionaryItem item = dictionary.getItem(card.getCardType());
//                String sourceDicId = (String) item.getProperty("dicId");
                // @@ 如果是就诊卡需要过滤非目的医院的卡。
//                if (sourceDicId == null || "hcn.base.dictionary.region".equals(sourceDicId) || card.getSource().equals(orgId)) {
//                    cardList.add(ImmutableMap.of("cardType", card.getCardType(), "cardNo", card.getCardNo(), "domain", card.getSource()));
//                }
            }
        }
        Map<String, Object> cert = constructCert(mpiId);
        return new Object[]{patientCode, orgId, executionType, cert, cardList};
    }

    /***
     * @Author: zhusm@bsoft.com.cn
     * @Description: 获取个人证件信息
     * @CreateTime: 19:55 2019/4/23
     * @Params: [mpiId]
     * @return: java.util.Map<java.lang.String, java.lang.String>
     **/
    private Map<String, Object> constructCert(String mpiId) throws ControllerException {
        Certificate certificate;
        try {
            if (StringUtils.isEmpty(mpiId)) {
                UserRoleToken urt = UserRoleToken.getCurrent();
                Unique unique = new Unique();
                unique.setUniqueId(urt.getUserId());
                unique.setSource(Constants.USERID_SOURCE);
                unique.setIdType(Constants.USERID_TYPE_CODE);

                mpiId = mpiProvider.getMpiIdByUnique(unique);
                if (mpiId == null) {
                    throw new ControllerException(CodeDefinition.DEMOGRAPHIC_FAIL, "获取个人信息失败。");
                }
            } else {
//                String master = ContextHelper.getSelfMpiId(mpiProvider);
//                if (null != master && !master.equals(mpiId)) {
//                    FamilyMember member = familyMemberDAO.getFamilyMember(master, mpiId);
//                    if (member == null) {
//                        throw new ControllerException(CodeDefinition.FAMILY_MEMBER_NOT_EXISTS, "目前只能为本人或者家庭成员支付费用。");
//                    }
//                }
            }
            certificate = mpiProvider.getCertificate(mpiId);
        } catch (MPIException e) {
            throw new ControllerException(CodeDefinition.DEMOGRAPHIC_FAIL, "获取证件,卡信息失败。");
        }
        String certificateType = IdentityTransformUtil.hcnIdentityToHuLian(certificate.getCertificateType());
        Map<String, Object> cert = certificate != null ? ImmutableMap.of("certificateType", certificateType,
                "certificateNo", SM4Utils.decryptData_ECB(certificate.getCertificateNo()), "nationality", certificate.getSource()) : null;
        return cert;
    }


    /***
     * @Author: zhusm@bsoft.com.cn
     * @Description: 构建自选卡信息数据
     * @CreateTime: 19:47 2019/4/23
     * @Params: [orgId, beginDate, endDate, cards]
     * @return: java.util.List<java.util.Map < java.lang.String, java.lang.String>>
     **/
    private Object[] constructCards(String mpiId, String orgId, String localOrgId, int executionType, List<UnpayedRecordsRequestBean.Card> cards) throws ControllerException {
        Map<String, Object> cert = constructCert(mpiId);
        //构建卡信息
        String patientCode = "";
        try {
            Set<Card> cardList = mpiProvider.getCards(mpiId);
            if (cardList != null && !cardList.isEmpty()) {
                for (Card card : cardList) {
                    //添加机构就诊卡入参
                    if (CommonUtils.isNotEmpty(orgId)) {
                        if (card.getSource().equals(orgId)) {
                            patientCode = card.getPatientCode();
                        }
                    }
                }
            }
        } catch (MPIException e) {
            e.printStackTrace();
        }
        List<Map<String, Object>> cardsMap = new ArrayList<>();
        for (UnpayedRecordsRequestBean.Card card : cards) {
            Map<String, Object> map = new HashMap<>();
            map.put("cardType", card.getCardType());
            map.put("cardNo", card.getCardNo());
            cardsMap.add(map);
        }
        return new Object[]{patientCode, localOrgId, executionType, cert, cardsMap};
    }

    /**
     * 获取预结算的结果。
     *
     * @return
     * @throws ControllerException
     */
    @RpcService
    public NewGetPrecalculatedFeeVO getPrecalculatedFee(PrecalculatedFeeRequestBean request) throws Exception {
        LOGGER.info("HCN-WEB获取预结算的结果入参--->{}", request);
        //复诊配药处方支付
        if (CommonUtils.isNotEmpty(request.getOrderId())) {
            GetDrugOrderPrecalculatedFeeQo qo = new GetDrugOrderPrecalculatedFeeQo();
            qo.setOrderId(request.getOrderId());
            try {
                NewGetPrecalculatedFeeVO newGetPrecalculatedFeeVO = (NewGetPrecalculatedFeeVO) Client.rpcInvoke("hcb.drugOrderService", "getDrugOrderPrecalculatedFee", qo);
                if (null != newGetPrecalculatedFeeVO) {
                    newGetPrecalculatedFeeVO.setVoucherIdList(request.getVoucherIdList());
                }
                return newGetPrecalculatedFeeVO;
            } catch (ControllerException e) {
                throw e;
            } catch (Throwable throwable) {
                throwable.printStackTrace();
                throw new ControllerException(CodeDefinition.CANNOT_GET_PRECALCULATE_FEE_RECORDS, "获取预结算的结果出错");
            }
        } else {
            Map<String, String> baseDicMap = new HashMap<>();
            List<QueryDicContrastListVo> queryDicContrastListVos = dicContrastService.queryDicContrastList("fee_type", request.getHospitalCode());
            if (CommonUtils.isNotEmpty(queryDicContrastListVos)) {
                for (QueryDicContrastListVo queryDicContrastListVo : queryDicContrastListVos) {
                    baseDicMap.put(queryDicContrastListVo.getBaseItemCode(), queryDicContrastListVo.getHisItemCode());
                }
            }

            List<String> duplicated = new ArrayList<>();
            for (NewGetPrecalculatedFeeRequestBean.FeeRecordsBean feeRecordsBean : request.getFeeRecords()) {
                String detailId = request.getHospitalCode() + "^" + feeRecordsBean.getFeeTypeCode() + "^" + feeRecordsBean.getFeeNo();
                List<DiagnosisPayTradeDetail> details = payTradeService.findByDetailId(detailId);
                if (details != null && !details.isEmpty()) {
                    for (DiagnosisPayTradeDetail detail : details) {
                        PayTrade payTrade = payTradeIntf.getPayTrade(detail.getTradeNo());
                        TradeStatus tradeStatus = TradeStatus.getTradeStatus(payTrade.getTradeStatus());
                        if (tradeStatus == TradeStatus.successful || tradeStatus == TradeStatus.appSucceed) {
                            duplicated.add(feeRecordsBean.getFeeNo());
                            break;
                        }
                    }
                }
                //把标准的字段对照转换为his的字典
                if (baseDicMap.keySet().contains(feeRecordsBean.getFeeTypeCode())) {
                    feeRecordsBean.setFeeTypeCode(baseDicMap.get(feeRecordsBean.getFeeTypeCode()));
                }
            }
            if (!duplicated.isEmpty()) {
                throw new ControllerException(CodeDefinition.CANNOT_GET_PRECALCULATE_FEE_RECORDS, "获取预结算的结果出错");
            }

            Organization organization = organizationInfoService.getOrgDetailByOrgId(request.getHospitalCode());
            request.setHospitalCode(organization.getLocalOrgId());
            //获取his Url
            request.setHisUrl(organization.getProHisUrl());
            BasePropertyConfig propertyCode = basePropertyConfigIntf.getPropertyConfigByPropertyCode("013708", organization.getOrgId());
            BaseResponse<NewGetPrecalculatedFeeResponseBean> response = new BaseResponse<>();
            if (null != propertyCode && "1".equals(propertyCode.getPropertyData())) {
                response = invokeAdapter("hcnInterface.diagnosisPayTradeService", "getPrecalculatedFeeXML",
                        CodeDefinition.CANNOT_GET_PRECALCULATE_FEE_RECORDS, "获取费用预结算金额失败。", request);
            } else {
                response = invokeAdapter("hcnInterface.diagnosisPayTradeService", "getPrecalculatedFee",
                        CodeDefinition.CANNOT_GET_PRECALCULATE_FEE_RECORDS, "获取费用预结算金额失败。", request);
            }
            LOGGER.info("hcnInterface返回：{}", response);
            if (response.getCode() == ResponseCode.FEEFAIL) {
                throw new ControllerException(CodeDefinition.CANNOT_GET_PRECALCULATE_FEE_RECORDS, "此订单已经已经支付");
            }
            if (response.getCode() == ResponseCode.SUCCESS) {
                NewGetPrecalculatedFeeResponseBean newGetPrecalculatedFeeResponseBean = JSONObject.parseObject(JSONArray.toJSONString(response.getData()), NewGetPrecalculatedFeeResponseBean.class);
                List<NewGetPrecalculatedFeeResponseBean.CostItemsBean> mergingItems = newGetPrecalculatedFeeResponseBean.getMergingItems();
                NewGetPrecalculatedFeeVO.NewGetPrecalculatedFeeVOBuilder precalculatedFeeVO = NewGetPrecalculatedFeeVO.builder().amount(newGetPrecalculatedFeeResponseBean.getAmount())
                        .invoiceNumber(Objects.isNull(newGetPrecalculatedFeeResponseBean.getInvoiceNumber()) ? "" : newGetPrecalculatedFeeResponseBean.getInvoiceNumber())
                        .orgId(request.getHospitalCode())
                        .payAmount(newGetPrecalculatedFeeResponseBean.getPayAmount())
                        .paymentBudgetNumber(newGetPrecalculatedFeeResponseBean.getPaymentBudgetNumber())
                        .totalFee(newGetPrecalculatedFeeResponseBean.getTotalFee())
                        .deductionAmount(newGetPrecalculatedFeeResponseBean.getDeductionAmount())
                        .voucherIdList(request.getVoucherIdList());
                List<NewGetPrecalculatedFeeVO.CostItemsBean> costItemsBeans = new LinkedList<>();
                for (NewGetPrecalculatedFeeResponseBean.CostItemsBean costItemsBean : mergingItems) {
                    NewGetPrecalculatedFeeVO.CostItemsBean build = NewGetPrecalculatedFeeVO.CostItemsBean.builder().amount(costItemsBean.getAmount())
                            .mergingSubtotal(costItemsBean.getAmount())
                            .mergingCode(costItemsBean.getMergingCode())
                            .mergingName(costItemsBean.getMergingName()).build();
                    costItemsBeans.add(build);
                }
                return precalculatedFeeVO.mergingItems(costItemsBeans).build();
            }
            throw new ControllerException(CodeDefinition.CANNOT_GET_PRECALCULATE_FEE_RECORDS, "获取预结算的结果出错：" + response.getMessage());
        }
    }

    /**
     * @param params
     * @return
     * @throws ControllerException
     */
    @RpcService
    protected Map<String, Object> createOrderExtraInfo(String tradeNo, Map<String, Object> params) throws ControllerException {
        Object orgId = params.get("orgId");
        Object patientId = params.get("patientId");
        Object selfPay = params.get("totalFee");
        Object precalId = params.get("precalId");
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> feeRecords = (List<Map<String, Object>>) params.get("feeRecords");

        for (Map<String, Object> record : feeRecords) {
            DiagnosisPayTradeDetail detail = new DiagnosisPayTradeDetail();
            detail.setFeeNo((String) record.get("feeNo"));
            detail.setFeeType((String) record.get("feeTypeCode"));
            detail.setOrgId((String) orgId);
            detail.setTradeNo(tradeNo);
            detail.setDetailId(orgId + "^" + detail.getFeeType() + "^" + detail.getFeeNo());
            payTradeService.saveDiagnosisPayTradeDetail(detail);
        }

        Person person = null;
        try {
            person = ContextHelper.getSelfInfo(mpiProvider);
        } catch (MPIException e) {
            LOGGER.error("Cannot get person information for trade with No.: {}", tradeNo, e);
        }
        return new ImmutableMap.Builder<String, Object>()
                .put("orgId", orgId)
                .put("patientId", patientId)
                .put("tradeDate", new Date())
                .put("payer", (person == null || StringUtils.isEmpty(person.getPersonName())) ? "" : person.getPersonName())
                .put("selfPay", selfPay)
                .put("precalId", precalId)
                .put("feeRecords", feeRecords).build();
    }

    /**
     * 获取支付明细。
     *
     * @return
     * @throws ControllerException
     */
    @RpcService
    public NewGetFeeDetailResponseBean getFeeDetail(FeeDetailRequestBean request) throws Exception {
        try {
            ValidationUtil.validation(request);//入参格式校验
        } catch (AnnotaionException e) {
            e.printStackTrace();
            throw new ControllerException(CodeDefinition.CANNOT_GET_FEE_DETAIL, e.getMessage());
        }

        if (2 == request.getOutpatientType().intValue() || CommonUtils.isNotEmpty(request.getOrderId())) {
            //从本地获取云支付已支付详情数据
            if (CommonUtils.isEmpty(request.getOrderId())) {
                throw new ControllerException("订单号不能为空");
            }
            try {
                NewGetFeeDetailResponseBean responseBeans = (NewGetFeeDetailResponseBean) Client.rpcInvoke("hcb.cloudPayService", "queryLocalPayedRecordDetail", request);
                return responseBeans;
            } catch (Throwable throwable) {
                throwable.printStackTrace();
                throw new ControllerException(CodeDefinition.CANNOT_GET_PAYED_RECORDS, "获取已支付详情失败");
            }
        } else {
            //实时从his获取已支付详情
            LOGGER.info("HCN-WEB获取支付明细入参--->{}", request);

//            if (CommonUtils.isEmpty(request.getInvoiceNumber())) {
//                throw new ControllerException("发票号不能为空");
//            }
            if (CommonUtils.isEmpty(request.getPatientCode())) {
                throw new ControllerException("病人id不能为空");
            }
            Organization organization = organizationInfoService.getOrgDetailByOrgId(request.getOrgId());
            String localOrgId = organization.getLocalOrgId();
            BaseResponse<NewGetFeeDetailResponseBean> response = new BaseResponse<>();
            BasePropertyConfig propertyCode = basePropertyConfigIntf.getPropertyConfigByPropertyCode("013708", organization.getOrgId());
            if (null != propertyCode && "1".equals(propertyCode.getPropertyData())) {
                response = invokeAdapter("hcnInterface.diagnosisPayTradeService", "getFeeDetailXML",
                        CodeDefinition.CANNOT_GET_FEE_DETAIL, "获取费用明细失败。", localOrgId, request.getPatientCode(), request.getInvoiceNumber(), request.getPaymentNumber(), organization.getProHisUrl());
            } else {
                response = invokeAdapter("hcnInterface.diagnosisPayTradeService", "getFeeDetail",
                        CodeDefinition.CANNOT_GET_FEE_DETAIL, "获取费用明细失败。", localOrgId, request.getPatientCode(), request.getInvoiceNumber(), organization.getProHisUrl());
            }
            LOGGER.info("hcnInterface返回：{}", response);
            NewGetFeeDetailResponseBean responseBean = null;
            if (response.getCode() == ResponseCode.SUCCESS) {
                try {
                    Person person = mpiProvider.getPerson(request.getMpiId());
                    if (null != person) {
                        Unique unique = mpiProvider.getUnique(person.getMpiId(), Constants.USERID_SOURCE, Constants.USERID_TYPE_CODE);
                        String avatar = null;
                        if (null != unique) {
                            avatar = payTradeService.getAvatar(unique.getUniqueId());
                        }
                        responseBean = JSONObject.parseObject(JSONArray.toJSONString(response.getData()), NewGetFeeDetailResponseBean.class);
                        responseBean.setUserName(person.getPersonName());
                        responseBean.setAvatar(avatar == null || "".equals(avatar) ? "" : avatar);
//                        responseBean.setInvoiceNumber(request.getInvoiceNumber()); //ODS_getFeeDetail 已有返回
                    }

                    responseBean.setOrganizationId(localOrgId);

                    //查询发票信息
                    try {
                        Map<String, Object> requestMap = Maps.newHashMap();
                        requestMap.put("organizationId", organization.getLocalOrgId());
                        requestMap.put("queryType", 2);
                        requestMap.put("invoiceCode", responseBean.getInvoiceNumber());
                        requestMap.put("paymentNumber", request.getPaymentNumber());
                        List<Map<String, Object>> patientIdentityCardList = Lists.newArrayList();
                        Map<String, Object> cardMap = Maps.newHashMap();
                        cardMap.put("cardNumber", person.getCertificate().getCertificateNo());
                        cardMap.put("cardType", person.getCertificate().getCertificateType());
                        requestMap.put("patientIdentityCardList", patientIdentityCardList);
                        Map<String, Object> invoiceMap = (Map<String, Object>) Client.rpcInvoke("hce.electronicInvoiceService", "queryInvoiceInfo", requestMap);
                        //Map<String, Object> invoiceMap = (Map<String, Object>) Client.rpcInvoke("cmc.invoiceService", "queryInvoiceInfo", requestMap);
                        if (CommonUtils.isNotEmpty(invoiceMap)) {
                            if (CommonUtils.isNotEmpty(invoiceMap.get("billBatchCode"))) {
                                responseBean.setBillBatchCode(invoiceMap.get("billBatchCode").toString());
                            }
                            if (CommonUtils.isNotEmpty(invoiceMap.get("billNo"))) {
                                responseBean.setBillNo(invoiceMap.get("billNo").toString());
                            }
                            if (CommonUtils.isNotEmpty(invoiceMap.get("random"))) {
                                responseBean.setRandom(invoiceMap.get("random").toString());
                            }
                        }
                    } catch (Throwable throwable) {
                        LOGGER.info("获取电子票据失败", throwable.getMessage());
                    }

                    List<PayTrade> payTrades = payTradeIntf.queryLikeByExtraData("%\"invoiceNumber\":\"" + request.getInvoiceNumber() + "\"%", request.getOrgId());
                    if (CommonUtils.isNotEmpty(payTrades)) {
                        //前端花森秀要求这么给
                        responseBean.setMedicalDate(responseBean.getRefundTime());
                        responseBean.setRefundTime(DateUtils.toString(payTrades.get(0).getTradeTime(), "yyyy-MM-dd HH:mm:ss"));
                        responseBean.setPayType(PayType.getDisplay(payTrades.get(0).getPayType()));
                        responseBean.setAgtOrderNumber(payTrades.get(0).getPayServerTradeNo());
                        responseBean.setPayAmount(payTrades.get(0).getTotalFee() + "");
                        //前端花森秀要求这么给
                        responseBean.setDepartmentName(responseBean.getHospitalName() + responseBean.getDepartmentName());
                    }
                } catch (MPIException e) {
                    e.printStackTrace();
                    throw new ControllerException(CodeDefinition.CANNOT_GET_FEE_DETAIL, "获取支付明细出错：" + response.getMessage());
                }
                return responseBean;
            }
            throw new ControllerException(CodeDefinition.CANNOT_GET_FEE_DETAIL, "获取支付明细出错：" + response.getMessage());
        }
    }


    //模拟医院his推送的诊间支付待支付消息newGetUnpayListResponseBean
    public void notifyUnpayed(String mpiId, NewGetUnpayListResponseBean responseBean, Organization organization) throws ControllerException {
        try {
            //app端发送消息
            logger.info("模拟医院his推送的诊间支付待支付消息newGetUnpayListResponseBean" + JSONObject.toJSONString(responseBean));
            logger.info("模拟医院his推送的诊间支付待支付消息mpiId" + JSONObject.toJSONString(mpiId));
            logger.info("模拟医院his推送的诊间支付待支付消息organization" + JSONObject.toJSONString(organization));

            //app端发送消息
            Map<String, Object> map = null;
            map = personServiceIntf.getIdByMpiId(mpiId);

            if (CommonUtils.isEmpty(map)) {
                return;
            }
//            String mpiId2 = (String) map.get("mpiId");
            List<String> userIds = (List<String>) map.get("userId");

//            List<Device> patientDeviceList = new ArrayList<>();
//            Unique unique = null;
//            unique = mpiProvider.getUnique(mpiId, Constants.USERID_SOURCE, Constants.USERID_TYPE_CODE);
            try {
                Person person = mpiProvider.getPerson(mpiId);
            } catch (MPIException e1) {
                e1.printStackTrace();
            }
            if (userIds != null) {
                for (String userId : userIds) {
                    List<Device> patientDeviceList = new ArrayList<>();
//                    List<Device> patientUserDevice = DAOFactory.getDAO(DeviceDAO.class).findOnLineDevicesByUserId(userId, RoleIdEnum.PATIENT.title(), RpcUserToken.getTenantId());
//                    if (patientUserDevice != null) {
//                        patientDeviceList.addAll(patientUserDevice);
//                    }
//
//                    if (patientDeviceList.size() > 0) {
//
//                        PushMessageBean pushMessageBean = new PushMessageBean();
//                        pushMessageBean.setRoleId(RoleIdEnum.PATIENT.title());
//                        pushMessageBean.setNotificateType(String.valueOf(NotificationEvent.NotificateType.outpatient_fee_patient));
//                        pushMessageBean.setTemplateCode(MsgTemplateCode.OUTPATIENT_FEE_PATIENT001.getCode());
//                        pushMessageBean.setUserId(userId);
//
//                        Map<String, String> variableMap = new HashMap<String, String>();
//                        variableMap.put("#患者姓名#", person.getPersonName());
//                        variableMap.put("#医院名称#", organization.getFullName());
//
//                        Map<String, String> extra = new HashMap<String, String>();
//                        extra.put("orgId", organization.getOrgId());
//                        extra.put("orgName", organization.getFullName());
//                        extra.put("mpiId", mpiId);
//                        extra.put("name", person.getPersonName());
//                        extra.put("certificateType", person.getCertificate().getCertificateType());
//                        extra.put("certificateNo", person.getCertificate().getCertificateNo());
//                        pushMessageBean.setDeviceList(patientDeviceList);
//
//                        BaseResponse baseResponse = messageSyncService.productionMessage(pushMessageBean);
//                        if (ResultCode.SUCCESS != baseResponse.getCode()) {
//                            logger.error(baseResponse.getMessage());
//                        }

                        /*String content = person.getPersonName()+"：您在" + organization.getFullName() + "有1笔门诊费用待支付，请尽快处理";
                        NotificationEvent notificationEvent = new NotificationEvent(content, NotificationEvent.NotificateType.outpatient_fee_patient);
                        notificationEvent.addExtra("orgId", organization.getOrgId());
                        notificationEvent.addExtra("orgName", organization.getFullName());
                        notificationEvent.addExtra("mpiId", mpiId);
                        notificationEvent.addExtra("name",person.getPersonName());
                        notificationEvent.addExtra("certificateType",person.getCertificate().getCertificateType());
                        notificationEvent.addExtra("certificateNo",person.getCertificate().getCertificateNo());

                        notificationEvent.setDevices(patientDeviceList.toArray(new Device[patientDeviceList.size()]));
                        try {
                            //MQ发送极光消息
                            Client.rpcInvoke("hcn.sendAllKindsMsgService", "productionMessage", CopyUtils.copy(notificationEvent, PushMessageBean.class));
                        } catch (Throwable throwable) {
                            throwable.printStackTrace();
                        }*/
//                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }

    public String getAdapterServiceName() {
        return adapterServiceName;
    }

    public void setAdapterServiceName(String adapterServiceName) {
        this.adapterServiceName = adapterServiceName;
    }

    public String getGetUnpayedRecordsMethodName() {
        return getUnpayedRecordsMethodName;
    }

    public void setGetUnpayedRecordsMethodName(String getUnpayedRecordsMethodName) {
        this.getUnpayedRecordsMethodName = getUnpayedRecordsMethodName;
    }

    public String getGetPayedRecordsMethodName() {
        return getPayedRecordsMethodName;
    }

    public void setGetPayedRecordsMethodName(String getPayedRecordsMethodName) {
        this.getPayedRecordsMethodName = getPayedRecordsMethodName;
    }

    public String getGetPrecalculatedFeeMethodName() {
        return getPrecalculatedFeeMethodName;
    }

    public void setGetPrecalculatedFeeMethodName(String getPrecalculatedFeeMethodName) {
        this.getPrecalculatedFeeMethodName = getPrecalculatedFeeMethodName;
    }

    public String getGetFeeRecordDetailMethodName() {
        return getFeeRecordDetailMethodName;
    }

    public void setGetFeeRecordDetailMethodName(String getFeeRecordDetailMethodName) {
        this.getFeeRecordDetailMethodName = getFeeRecordDetailMethodName;
    }

    public IMPIProvider getMpiProvider() {
        return mpiProvider;
    }

    public void setMpiProvider(IMPIProvider mpiProvider) {
        this.mpiProvider = mpiProvider;
    }


    /**
     * @description: 查询可用抵用券列表
     * @author: chenJij@bsoft.com.cn
     * @date: 2021/9/17 7:26
     * @param: getUsableVoucherListQo
     * @return: java.util.List<hcn.protocol.ods.paymentXML.GetUsableVoucherListResp.Voucher>
     */
    @RpcService
    public List<GetUsableVoucherListResp.Voucher> queryUsableVoucherList(GetUsableVoucherListQo getUsableVoucherListQo) throws ControllerException {
        Organization organization = organizationInfoService.getOrgDetailByOrgId(getUsableVoucherListQo.getOrgId());

        GetUsableVoucherListReq getUsableVoucherListReq = new GetUsableVoucherListReq();
        getUsableVoucherListReq.setVisitOrganization(organization.getLocalOrgId());
        getUsableVoucherListReq.setIdCard(getUsableVoucherListQo.getIdCard());

        if (CommonUtils.isNotEmpty(getUsableVoucherListQo.getFeeRecords())) {
            List<String> feeRecords = new ArrayList<>();
            List<String> itemRecords = new ArrayList<>();
            for (NewGetPrecalculatedFeeRequestBean.FeeRecordsBean feeRecordsBean : getUsableVoucherListQo.getFeeRecords()) {
                feeRecords.add(feeRecordsBean.getFeeNo());
                if(CommonUtils.isNotEmpty(feeRecordsBean.getVoucherItemId())){
                    itemRecords.add(feeRecordsBean.getVoucherItemId());
                }
            }
            getUsableVoucherListReq.setFeeRecords(feeRecords);
            getUsableVoucherListReq.setItemRecords(itemRecords);
        }


        try {
            GetUsableVoucherListResp getUsableVoucherListResp = (GetUsableVoucherListResp) Client.rpcInvoke("hcnInterface.diagnosisPayTradeService", "getUsableVoucherList", getUsableVoucherListReq);

            if (null != getUsableVoucherListResp) {
                return getUsableVoucherListResp.getVoucherList();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ControllerException("查询可用抵用券列表失败");
        }
        return null;
    }
}
